﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using Oxite.Infrastructure;
using Oxite.Results;
using Oxite.Extensions;
using Oxite.Models;
using Oxite.ViewModels;
using Oxite.Filters;
using Oxite.Skinning;
using ECube.SEC.Services;

namespace ECube.SEC.Filters
{
    public class ECubeAuthorizationFilter : IAuthorizationFilter
    {

        private readonly IModulesLoaded modules;
        private readonly IAuthorizeService service;
        private readonly IUnityContainer container;
        
        public ECubeAuthorizationFilter(IUnityContainer container, IModulesLoaded modules,IAuthorizeService service)
        {
            this.container = container;
            this.modules = modules;
            this.service = service;
        }
        #region IAuthorizationFilter 成员

        public void OnAuthorization(AuthorizationContext filterContext)
        {
            bool allowAnonymous = filterContext.RouteData.Values.ContainsKey("AllowAnonymous") && bool.Equals(filterContext.RouteData.Values["AllowAnonymous"],true);
            bool isAuthorized = true;
            IUser user = null;
            if (!allowAnonymous)
            {
                IEnumerable<IOxiteAuthenticationModule> authenticationModules = modules.GetModules<IOxiteAuthenticationModule>().Reverse();
                

                foreach (IOxiteAuthenticationModule module in authenticationModules)
                {
                    user = module.GetUser(filterContext.RequestContext);
                    if (user.IsAuthenticated)
                    {
                        if (!HasPermission(user, filterContext))
                        {
                            isAuthorized = false;

                        }
                        break;
                    }
                }

                if (user == null || !user.IsAuthenticated)
                {
                    string signInUrl = authenticationModules.First().GetSignInUrl(filterContext.RequestContext);

                    if (filterContext.HttpContext.Request.IsAjaxRequest())
                       filterContext.Result = new JsonResult { Data = new AjaxRedirect(signInUrl) };
                    else
                       filterContext.Result = new RedirectResult(signInUrl);
                }

            }

            if (!isAuthorized)
            {
                filterContext.Result = new UnauthorizedResult(container, new UserViewModel(user));
                
            }
        }
                
        #endregion

        public bool HasPermission( IUser user, AuthorizationContext context)
        {
            return true;
            string permissionKey = context.Controller.GetType().FullName + "_" + context.ActionDescriptor.ActionName;
            return HasPermission(user, permissionKey);
        }
        public bool HasPermission(IUser user, string permissionKey)
        {
            if (this.service == null) return false;

            return this.service.GetPermissionsForUser(user).Any(p => permissionKey.Equals(p,StringComparison.OrdinalIgnoreCase));
            
        }
    }
}
